/*
 * Copyright (c) 2015 Messcat. All rights reserved.
 */
package cc.messcat.web.system;

import cc.messcat.common.constant.CommonConstant;
import cc.messcat.common.constant.CommonRedisConstant;
import cc.messcat.common.model.ResponseBean;
import cc.messcat.common.util.BeanUtil;
import cc.messcat.common.util.CollectionUtil;
import cc.messcat.common.util.LogUtil;
import cc.messcat.entity.area.Area;
import cc.messcat.entity.level.UserLevel;
import cc.messcat.entity.system.McUser;
import cc.messcat.entity.system.Role;
import cc.messcat.entity.website.LevelVO;
import cc.messcat.log.OperationLog;
import cc.messcat.service.system.PermissionService;
import cc.messcat.service.system.SystemService;
import cc.messcat.service.system.UserService;
import cc.messcat.util.Collections;
import cc.messcat.util.LevelUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * 登录功能处理
 *
 * @author Microcat
 * @version 1.0
 */
@Controller
public class LoginController {

    @Autowired
    private UserService userService;
    
	@Autowired
	private PermissionService permissionService;
	
	@Autowired
	private SystemService systemService;
	
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login() {
        return "login";
    }

    @OperationLog(desc="网页端登录",module="登录")
    @RequestMapping(value = "/goLoginning", method = RequestMethod.POST)
    public String goLoginning(Model model, @RequestParam("mc_username") String username,
                              @RequestParam("mc_password") String password,HttpSession session)throws Exception {
        String error = null;
        try {
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
            subject.getSession().setAttribute(CommonRedisConstant.REDIS_KEY_LOGIN_USER, username);
            McUser user = userService.modifyForLogin(username);
            subject.getSession().setAttribute("userId", user.getId());
            
            //用户角色不能为空
            Set<Role> roleSet = user.getRoles();
            if ("0".equals(user.getStatus())) {
                error = "<span style='color:red'>该用户已停用</span>";
                model.addAttribute("mc_login_error", error);
                return "login";
            }
            
            //角色状态判断
            boolean invalid = false;
            Iterator<Role> it = roleSet.iterator();
            while(it.hasNext()){
                Role r = it.next();
                //该角色停用
                if("1".equals(r.getStatus())) {
                	it.remove();
                	invalid = true;
            	}
            }
            
            if (CollectionUtil.isSetEmpty(roleSet)) {
            	error = invalid ? "<span style='color:red'>该用户所绑定的角色已停用 </span>" : "<span style='color:red'>该用户没有绑定角色，暂不可用</span>";
            	model.addAttribute("mc_login_error", error);
            	return "login";
            }
            
            subject.getSession().setAttribute("businessAnnual",session.getServletContext().getAttribute("businessAnnual"));
            subject.getSession().setAttribute("user", user);
            subject.getSession().setAttribute("realName", user.getRealName());
            subject.getSession().setAttribute("userLevel", user.getUserLevel().getLevel());
            subject.getSession().setAttribute("userType", user.getType());
            subject.getSession().setAttribute("mobile", user.getMobilePhone());
            List<LevelVO> list = searchAreaByLevel(user);
            subject.getSession().setAttribute("areaList", list);
        } catch (UnknownAccountException | IncorrectCredentialsException e) {
            error = "<span style='color:red'>用户名或密码不匹配</span>";
            LogUtil.logException("LoginController.goLoginning", e);
        } catch (AuthenticationException e) {
            error = "<span style='color:red'>登录异常，请重新登录</span>";
            LogUtil.logException("LoginController.goLoginning", e);
        }
        if (error != null) {// 出错了，返回登录页面
            model.addAttribute("mc_login_error", error);
            return "login";
        }
//		model.addAttribute("username", username);
        return "redirect:/welcome";
    }
    
    /**
     * app登录
     * @param model
     * @param username
     * @param password
     * @return
     */
    @OperationLog(desc="APP端登录",module="登录")
    @RequestMapping(value = "/appLogin",method=RequestMethod.POST)
    @ResponseBody
    public Object appLogin(Model model, @RequestParam("mc_username") String username,
                              @RequestParam("mc_password") String password,HttpSession session)throws Exception {
        String error = null;
        McUser user = null;
        try {
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
            subject.getSession().setAttribute(CommonRedisConstant.REDIS_KEY_LOGIN_USER, username);
            user = userService.modifyForLogin(username);
            //审核不通过，不允许登录
            if("审核不通过".equals(user.getCheckState())){
            	error = "账号审核不通过";
            	return new ResponseBean(CommonConstant.FAIL_CODE_400, error, null);
            }
            subject.getSession().setAttribute("userId", user.getId());
            //用户角色不能为空
            Set<Role> roleSet = user.getRoles();
            if ("0".equals(user.getStatus())) {
                error = "该用户已停用";
                model.addAttribute("mc_login_error", error);
                return new ResponseBean(CommonConstant.FAIL_CODE_400, error, null);
            }
            
            //角色状态判断
            boolean invalid = false;
            Iterator<Role> it = roleSet.iterator();
            while(it.hasNext()){
                Role r = it.next();
                //该角色停用
                if("1".equals(r.getStatus())) {
                	it.remove();
                	invalid = true;
            	}
            }
            //未审核的用户没有角色
            if(!"未审核".equals(user.getCheckState())){
	            if (CollectionUtil.isSetEmpty(roleSet)) {
	            	error = invalid ? "该用户所绑定的所有角色已停用，无法登陆 " : "该用户没有绑定角色，暂不可用";
	            	model.addAttribute("mc_login_error", error);
	            	return new ResponseBean(CommonConstant.FAIL_CODE_400, error, null);
	            }
            }
            subject.getSession().setAttribute("user", user);
            subject.getSession().setAttribute("realName", user.getRealName());
            //未审核也可以登录
            if(!"未审核".equals(user.getCheckState())){
            	subject.getSession().setAttribute("userLevel", user.getUserLevel().getLevel());
            }
            subject.getSession().setAttribute("userType", user.getType());
            subject.getSession().setAttribute("mobile", user.getMobilePhone());
            List<LevelVO> list = searchAreaByLevel(user);
            subject.getSession().setAttribute("areaList", list);
            //设置用户的审核状态
            subject.getSession().setAttribute("checkState", user.getCheckState());
        } catch (UnknownAccountException | IncorrectCredentialsException e) {
            error = "用户名或密码不匹配";
            LogUtil.logException("LoginController.goLoginning", e);
        } catch (AuthenticationException e) {
            error = "登录异常，请重新登录";
            LogUtil.logException("LoginController.goLoginning", e);
        }
        if (error != null) {// 出错了，返回登录页面
            model.addAttribute("mc_login_error", error);
            return new ResponseBean(CommonConstant.FAIL_CODE_400, error, null);
        }
//		model.addAttribute("username", username);
        
        return new ResponseBean(CommonConstant.SUCCESS_CODE_200, "登录成功", 
        	Collections.generateHashMap(
        		"businessAnnual",session.getServletContext().getAttribute("businessAnnual"),
        		"type", session.getAttribute("userType"),
        		"mobile",session.getAttribute("mobile"),
        		"checkState",session.getAttribute("checkState")));
    }

    private List<LevelVO> searchAreaByLevel(McUser user) {
        UserLevel userLevel = user.getUserLevel();
        if (!BeanUtil.isValid(userLevel) || !BeanUtil.isValid(user.getAreaId())) return null;
        List<LevelVO> list = new ArrayList<>();
        Long areaId = user.getAreaId();
        Area area;
        for (Integer level = userLevel.getLevel(); level > 0; level--) {
            area = userService.retrieveObject(Area.class, areaId);
            list.add(createLevelVO(level, area));
            areaId = area.getFatherId();
        }
        return list;
    }

    private LevelVO createLevelVO(Integer level, Area area) {
        LevelVO lv = new LevelVO();
        lv.setName(LevelUtil.Level.getLevelName(level));
        lv.setValue(area);
        return lv;
    }

    @RequestMapping(value = "/welcome", method = RequestMethod.GET)
    public String welcome() {
        return "hui_index";
    }

}